#pragma once
#include "NoCopy.hpp"
#include "UdpSocket.hpp"
#include "InetAddr.hpp"
#include <iostream>
#include <string>
#include <vector>
#include <cassert>
#define PORT 8888
typedef struct sockaddr sockaddr; 
typedef struct sockaddr_in sockaddr_in; 
class UdpServer : public NoCopy
{
    void AddOnlineUser(InetAddr addr)
    {
        for (auto& e : _addrs)
        {
            if (e == addr) return;
        }
        _addrs.push_back(addr);
    }
public:
    UdpServer(u_int16_t port = PORT)
        :_port(port)
    {
        
    }
    void Init()
    {
        assert(_sock.Socket());
        assert(_sock.Bind(INADDR_ANY, _port));
    }
    void Start()
    {
        while (true)
        {
            std::string message;
            std::string ip;
            uint16_t port;
            if (_sock.RecvFrom(&message, &ip, &port))
            {
                sockaddr_in clientaddr;
                clientaddr.sin_family = AF_INET;
                clientaddr.sin_port = htons(port);
                inet_aton(ip.c_str() ,&clientaddr.sin_addr);
                AddOnlineUser(clientaddr);
            }
        }
    }
    ~UdpServer()
    {
        _sock.Close();
    }
private:
    UdpSocket _sock;
    uint16_t _port;
    std::vector<InetAddr> _addrs;
};